package de.saarland.uni.lego3d.server.gui.emulator;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class KinectEmulator {
	
	protected int MSG_FORWARD = 0;
	protected int MSG_BACKWARD = 0;
	protected int MSG_LEFT = 0;
	protected int MSG_RIGHT = 0;
	protected int MSG_UP = 0;
	protected int MSG_DOWN = 0;
	protected boolean MSG_SWIPE_LEFT = false;
	protected boolean MSG_SWIPE_RIGHT = false;
	protected boolean MSG_CLICK = false;
	protected boolean MSG_ACTIVE_MOUSE = false;
	protected boolean MSG_ACTIVE_BLOCK = false;
	
	private int port = 9876;
	private String address = "127.0.0.1";
	protected DatagramSocket socket = null;
	protected DatagramPacket outgoing;
	protected byte[] data = new byte[256];
	
	Thread t;
	
	/**
	 * Simple emulator for kinect messages.
	 * Not very nice, not very good documented. It has only been used for debugging if no kinect device was available.
	 * Just added to our project to give you everything we have done
	 */
	public KinectEmulator() {
		
		try {
			socket = new DatagramSocket();
			socket.connect(InetAddress.getByName(address), port);
			socket.setSoTimeout(15000);
			socket.setReceiveBufferSize(32768);
			socket.setSendBufferSize(32768);
		} catch (SocketException e1) {
			e1.printStackTrace();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
		
		//GUI
		KinectEmuGUI gui = new KinectEmuGUI();
	}
	
	private class SendThread extends Thread {

		@Override
		public void run() {
			StringBuilder strb = new StringBuilder();

			while (!isInterrupted()) {
				
				strb = new StringBuilder();
				
				strb.append("KINECT-ACTION");
				strb.append("#" + MSG_FORWARD);
				strb.append("#" + MSG_BACKWARD);
				strb.append("#" + MSG_LEFT);
				strb.append("#" + MSG_RIGHT);
				strb.append("#" + MSG_UP);
				strb.append("#" + MSG_DOWN);
				strb.append("#" + MSG_SWIPE_LEFT);
				strb.append("#" + MSG_SWIPE_RIGHT);
				strb.append("#" + MSG_CLICK);
				strb.append("#" + MSG_ACTIVE_MOUSE);
				strb.append("#" + MSG_ACTIVE_BLOCK);
				
				data = strb.toString().getBytes();
				outgoing = new DatagramPacket(data, data.length);
				try {
					socket.send(outgoing);
				} catch (IOException e) {
					e.printStackTrace();
				}
				
				try {
					sleep(50);
				} catch (InterruptedException e) {
					interrupt();
				}
			}
		}
	}
	
	private class KinectEmuGUI extends JFrame {
		public KinectEmuGUI() {
			super("Saarland University - Lego3D - KinctEmulator");
			setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			setResizable(true);
			setPreferredSize(new Dimension(200, 550));
			getContentPane().setBackground(Color.WHITE);
			getContentPane().setLayout(new GridLayout(13, 1));
			
			JPanel pForward = new JPanel(new BorderLayout());
			JLabel label = new JLabel("Forward", JLabel.CENTER);
			pForward.setBackground(Color.BLACK);
			label.setForeground(Color.WHITE);
			label.setBackground(Color.DARK_GRAY);
			JSlider slider = new JSlider(JSlider.HORIZONTAL, 0, 100, 0);
			slider.setBackground(Color.WHITE);
			slider.addChangeListener(new ChangeListener() {
				@Override
				public void stateChanged(ChangeEvent arg0) {
					MSG_FORWARD = ((JSlider) arg0.getSource()).getValue();
				}
			});
			pForward.add(label, BorderLayout.NORTH);
			pForward.add(slider, BorderLayout.CENTER);
			getContentPane().add(pForward);
			
			JPanel pBackward = new JPanel(new BorderLayout());
			label = new JLabel("Backward", JLabel.CENTER);
			pBackward.setBackground(Color.BLACK);
			label.setForeground(Color.WHITE);
			label.setBackground(Color.DARK_GRAY);
			slider = new JSlider(JSlider.HORIZONTAL, 0, 100, 0);
			slider.setBackground(Color.WHITE);
			slider.addChangeListener(new ChangeListener() {
				@Override
				public void stateChanged(ChangeEvent arg0) {
					MSG_BACKWARD = ((JSlider) arg0.getSource()).getValue();
				}
			});
			pBackward.add(label, BorderLayout.NORTH);
			pBackward.add(slider, BorderLayout.CENTER);
			getContentPane().add(pBackward);
			
			JPanel pLeft = new JPanel(new BorderLayout());
			label = new JLabel("Left", JLabel.CENTER);
			pLeft.setBackground(Color.BLACK);
			label.setForeground(Color.WHITE);
			label.setBackground(Color.DARK_GRAY);
			slider = new JSlider(JSlider.HORIZONTAL, 0, 100, 0);
			slider.setBackground(Color.WHITE);
			slider.addChangeListener(new ChangeListener() {
				@Override
				public void stateChanged(ChangeEvent arg0) {
					MSG_LEFT = ((JSlider) arg0.getSource()).getValue();
				}
			});
			pLeft.add(label, BorderLayout.NORTH);
			pLeft.add(slider, BorderLayout.CENTER);
			getContentPane().add(pLeft);
			
			JPanel pRight = new JPanel(new BorderLayout());
			label = new JLabel("Right", JLabel.CENTER);
			pRight.setBackground(Color.BLACK);
			label.setForeground(Color.WHITE);
			label.setBackground(Color.DARK_GRAY);
			slider = new JSlider(JSlider.HORIZONTAL, 0, 100, 0);
			slider.setBackground(Color.WHITE);
			slider.addChangeListener(new ChangeListener() {
				@Override
				public void stateChanged(ChangeEvent arg0) {
					MSG_RIGHT = ((JSlider) arg0.getSource()).getValue();
				}
			});
			pRight.add(label, BorderLayout.NORTH);
			pRight.add(slider, BorderLayout.CENTER);
			getContentPane().add(pRight);
			
			JPanel pUp = new JPanel(new BorderLayout());
			label = new JLabel("Up", JLabel.CENTER);
			pUp.setBackground(Color.BLACK);
			label.setForeground(Color.WHITE);
			label.setBackground(Color.DARK_GRAY);
			slider = new JSlider(JSlider.HORIZONTAL, 0, 100, 0);
			slider.setBackground(Color.WHITE);
			slider.addChangeListener(new ChangeListener() {
				@Override
				public void stateChanged(ChangeEvent arg0) {
					MSG_UP = ((JSlider) arg0.getSource()).getValue();
				}
			});
			pUp.add(label, BorderLayout.NORTH);
			pUp.add(slider, BorderLayout.CENTER);
			getContentPane().add(pUp);
			
			JPanel pDown = new JPanel(new BorderLayout());
			label = new JLabel("Down", JLabel.CENTER);
			pDown.setBackground(Color.BLACK);
			label.setForeground(Color.WHITE);
			label.setBackground(Color.DARK_GRAY);
			slider = new JSlider(JSlider.HORIZONTAL, 0, 100, 0);
			slider.setBackground(Color.WHITE);
			slider.addChangeListener(new ChangeListener() {
				@Override
				public void stateChanged(ChangeEvent arg0) {
					MSG_DOWN = ((JSlider) arg0.getSource()).getValue();
				}
			});
			pDown.add(label, BorderLayout.NORTH);
			pDown.add(slider, BorderLayout.CENTER);
			getContentPane().add(pDown);
			
			JPanel pSLeft = new JPanel(new BorderLayout());
			label = new JLabel("Swipe left", JLabel.CENTER);
			pSLeft.setBackground(Color.BLACK);
			label.setForeground(Color.WHITE);
			label.setBackground(Color.DARK_GRAY);
			JRadioButton onRBtn = new JRadioButton("TRUE");
			onRBtn.setActionCommand("true");
			JRadioButton offRBtn = new JRadioButton("FALSE");
			offRBtn.setActionCommand("false");
			offRBtn.setSelected(true);
		    ButtonGroup group = new ButtonGroup();
		    group.add(onRBtn);
		    group.add(offRBtn);
		    ActionListener rAction = new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					MSG_SWIPE_LEFT = Boolean.parseBoolean(e.getActionCommand()); 
				}
			};
			onRBtn.addActionListener(rAction);
			offRBtn.addActionListener(rAction);
			pSLeft.add(label, BorderLayout.NORTH);
			JPanel btnPanel = new JPanel(new GridLayout(1, 2));
			onRBtn.setBackground(Color.WHITE);
			offRBtn.setBackground(Color.WHITE);
			btnPanel.add(onRBtn);
			btnPanel.add(offRBtn);
			pSLeft.add(btnPanel, BorderLayout.CENTER);
			getContentPane().add(pSLeft);
			
			JPanel pSRight = new JPanel(new BorderLayout());
			label = new JLabel("Swipe right", JLabel.CENTER);
			pSRight.setBackground(Color.BLACK);
			label.setForeground(Color.WHITE);
			label.setBackground(Color.DARK_GRAY);
			onRBtn = new JRadioButton("TRUE");
			onRBtn.setActionCommand("true");
			offRBtn = new JRadioButton("FALSE");
			offRBtn.setActionCommand("false");
			offRBtn.setSelected(true);
		    ButtonGroup group2 = new ButtonGroup();
		    group2.add(onRBtn);
		    group2.add(offRBtn);
		    rAction = new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					MSG_SWIPE_RIGHT = Boolean.parseBoolean(e.getActionCommand()); 
				}
			};
			onRBtn.addActionListener(rAction);
			offRBtn.addActionListener(rAction);
			pSRight.add(label, BorderLayout.NORTH);
			btnPanel = new JPanel(new GridLayout(1, 2));
			onRBtn.setBackground(Color.WHITE);
			offRBtn.setBackground(Color.WHITE);
			btnPanel.add(onRBtn);
			btnPanel.add(offRBtn);
			pSRight.add(btnPanel, BorderLayout.CENTER);
			getContentPane().add(pSRight);
			
			JPanel pClick = new JPanel(new BorderLayout());
			label = new JLabel("Click", JLabel.CENTER);
			pClick.setBackground(Color.BLACK);
			label.setForeground(Color.WHITE);
			label.setBackground(Color.DARK_GRAY);
			onRBtn = new JRadioButton("TRUE");
			onRBtn.setActionCommand("true");
			offRBtn = new JRadioButton("FALSE");
			offRBtn.setActionCommand("false");
			offRBtn.setSelected(true);
		    ButtonGroup group3 = new ButtonGroup();
		    group3.add(onRBtn);
		    group3.add(offRBtn);
		    rAction = new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					MSG_CLICK = Boolean.parseBoolean(e.getActionCommand()); 
				}
			};
			onRBtn.addActionListener(rAction);
			offRBtn.addActionListener(rAction);
			pClick.add(label, BorderLayout.NORTH);
			btnPanel = new JPanel(new GridLayout(1, 2));
			onRBtn.setBackground(Color.WHITE);
			offRBtn.setBackground(Color.WHITE);
			btnPanel.add(onRBtn);
			btnPanel.add(offRBtn);
			pClick.add(btnPanel, BorderLayout.CENTER);
			getContentPane().add(pClick);
			
			JPanel pMouseMode = new JPanel(new BorderLayout());
			label = new JLabel("Mouse-mode", JLabel.CENTER);
			pMouseMode.setBackground(Color.BLACK);
			label.setForeground(Color.WHITE);
			label.setBackground(Color.DARK_GRAY);
			onRBtn = new JRadioButton("TRUE");
			onRBtn.setActionCommand("true");
			offRBtn = new JRadioButton("FALSE");
			offRBtn.setActionCommand("false");
			offRBtn.setSelected(true);
		    ButtonGroup group4 = new ButtonGroup();
		    group4.add(onRBtn);
		    group4.add(offRBtn);
		    rAction = new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					MSG_ACTIVE_MOUSE = Boolean.parseBoolean(e.getActionCommand()); 
				}
			};
			onRBtn.addActionListener(rAction);
			offRBtn.addActionListener(rAction);
			pMouseMode.add(label, BorderLayout.NORTH);
			btnPanel = new JPanel(new GridLayout(1, 2));
			onRBtn.setBackground(Color.WHITE);
			offRBtn.setBackground(Color.WHITE);
			btnPanel.add(onRBtn);
			btnPanel.add(offRBtn);
			pMouseMode.add(btnPanel, BorderLayout.CENTER);
			getContentPane().add(pMouseMode);
			
			JPanel pBrickMode = new JPanel(new BorderLayout());
			label = new JLabel("Brick-mode", JLabel.CENTER);
			pBrickMode.setBackground(Color.BLACK);
			label.setForeground(Color.WHITE);
			onRBtn = new JRadioButton("TRUE");
			onRBtn.setActionCommand("true");
			offRBtn = new JRadioButton("FALSE");
			offRBtn.setActionCommand("false");
			offRBtn.setSelected(true);
		    ButtonGroup group5 = new ButtonGroup();
		    group5.add(onRBtn);
		    group5.add(offRBtn);
		    rAction = new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					MSG_ACTIVE_BLOCK = Boolean.parseBoolean(e.getActionCommand()); 
				}
			};
			onRBtn.addActionListener(rAction);
			offRBtn.addActionListener(rAction);
			pBrickMode.add(label, BorderLayout.NORTH);
			btnPanel = new JPanel(new GridLayout(1, 2));
			onRBtn.setBackground(Color.WHITE);
			offRBtn.setBackground(Color.WHITE);
			btnPanel.add(onRBtn);
			btnPanel.add(offRBtn);
			pBrickMode.add(btnPanel, BorderLayout.CENTER);
			getContentPane().add(pBrickMode);
			
			JButton startBtn = new JButton("Start");
			startBtn.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					if (t == null) {
						t = new SendThread();
						t.start();
					}
				}
			});
			getContentPane().add(startBtn);
			
			JButton stopBtn = new JButton("Stop");
			stopBtn.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					if (t != null) {
						t.interrupt();
						try {
							t.join(1000);
							t = null;
						} catch (InterruptedException e1) {
							e1.printStackTrace();
						}
					}
				}
			});
			getContentPane().add(stopBtn);
			
			pack();
			setVisible(true);
		}
	}
	
	
	public static void main (String[] args) {
		KinectEmulator emu = new KinectEmulator();
	}
	
}

